

"""
Base Classes
A file for all the various base classes, interfaces, etc.
"""

import directions
from movementData import Plot, Move
from point import Point
from utils import frange

class Movable(object):
	location = property(lambda self: self.container.getCoord(self), 
					    lambda self, pos: self.container.moveItemTo(self, pos))
	direction = directions.North
	speedInfo = None
	container = None
	_plot=None
	plot = property(lambda self: self._plot)

	def __init__(self, container, initLoc=Point(0.0, 0.0),
				 initDir=directions.North, **kwargs):
		super(Movable, self).__init__(**kwargs)
		self.direction = initDir
		self.container = container
		self.container.append(self, initLoc)

	def getMaxMove(self, direction):
		"""Return the max distance movable in the given direction.
		"""
		return self.speedInfo[direction]

	def getAutoMove(self):
		"""Set an automatically-generated move for the current turn."""
		raise NotImplementedError

	def getPotentialMoves(self):
		"""Return a dictionary of possible moves for each compass point."""
		rv = {}
		for d in directions.compass:
			rv[d] = self.getMaxMove(d)

	def validatePlot(self):
		"""Make sure we can do our plotted move."""
		if len(self._plot) == 0: return True
		used = 0
		for p in self._plot:
			used += float(p.dist)/self.getMaxMove(p.dir)
			if used > (1 + 1.0/8.0):
				return False
		return True

	def move(self):
		"""Moves the currently plotted move without animation.
		
		Can raise an AssertionError if the plot we are tracking is not
		actually ours.
		"""
		# Validate our plot
		newplot = self._plot
		assert newplot.owner is self, "Not our plot!"
		# Make sure we have an iterable collection of moves
		if not hasattr(newplot, '__iter__'):
			newplot = [ newplot ]
		if len(newplot) == 0:
			newplot = [ self.getAutoMove() ]
		for vector in self._plot:
			#We assume the plot is valid.
			self.container.moveItem(self, vector)
		self.direction = vector.dir
		self._plot = Plot(self, [])
